// future.cpp


#include <csignal>
#include <cstdio>
#include <cstdlib>

#include <chrono>
#include <future>
#include <string>
#include <thread>


namespace blogs {


using std::chrono::milliseconds;
using std::future;
using std::launch;
using std::string;


class Data
{

  private:

    string
    __content__;


  public:

    Data(int count, char c)
        : __content__(count, c)
    {
    }


    string
    get_content()
    {
        return __content__;
    }

};


class Host
{

  public:

    future<Data>
    request(int count, char c)
    {
        std::printf("   request(%d, %c) BEGIN\n", count, c);
        future<Data> f = std::async(launch::deferred | launch::async,
                                    [=]() -> Data {
                                        for (int i = 0; i < count; ++i)
                                            std::this_thread::sleep_for(milliseconds(100));
                                        return Data(count, c);
                                    });
        std::printf("   request(%d, %c) END\n", count, c);
        return f;
    }

};


void
bye(int sig = SIGTERM)
{
    std::printf("\nBye Future...\n\n");
    std::exit(sig);
}


} // end of namespace blogs


int
main(int argc, char * argv[])
{
    using std::chrono::milliseconds;
    using std::future;
    using blogs::Data;
    using blogs::Host;

    std::signal(SIGINT, blogs::bye);

    std::printf("main BEGIN\n");

    Host host;
    future<Data> f1(host.request(30, 'A'));
    future<Data> f2(host.request(40, 'B'));
    future<Data> f3(host.request(50, 'C'));

    std::printf("main other Job BEGIN\n");
    std::this_thread::sleep_for(milliseconds(2000));
    std::printf("main other Job END\n");

    Data data1 = f1.get();
    Data data2 = f2.get();
    Data data3 = f3.get();

    std::printf("data1 = %s\n", data1.get_content().c_str());
    std::printf("data2 = %s\n", data2.get_content().c_str());
    std::printf("data3 = %s\n", data3.get_content().c_str());
    std::printf("main END\n");

    blogs::bye();
    return 0;
}

